package com.yida.gwj.vote.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.yida.common.core.domain.R;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.file.FileTypeUtils;
import com.yida.common.core.utils.file.MimeTypeUtils;
import com.yida.common.core.web.controller.BaseController;
import com.yida.common.core.web.domain.AjaxResult;
import com.yida.common.core.web.page.TableDataInfo;
import com.yida.common.log.annotation.Log;
import com.yida.common.log.enums.BusinessType;
import com.yida.common.security.annotation.InnerAuth;
import com.yida.common.security.annotation.Logical;
import com.yida.common.security.annotation.RequiresPermissions;
import com.yida.gwj.api.domain.dto.GwjGVoteProjectStatisticsDataDTO;
import com.yida.gwj.common.valid.Save;
import com.yida.gwj.common.valid.Update;
import com.yida.gwj.vote.domain.GwjMaintenanceFundsBusiness;
import com.yida.gwj.vote.domain.GwjVoteHouse;
import com.yida.gwj.vote.domain.GwjVoteProject;
import com.yida.gwj.vote.domain.dto.GwjBaseHouseOwnerDTO;
import com.yida.gwj.vote.domain.dto.GwjEVoteProjectStatisticsDataDTO;
import com.yida.gwj.vote.domain.dto.GwjVoteProjectDetailDTO;
import com.yida.gwj.vote.domain.dto.GwjVoteProjectListDTO;
import com.yida.gwj.vote.domain.request.*;
import com.yida.gwj.vote.enums.GwjVoteInitiateTypeEnum;
import com.yida.gwj.vote.enums.GwjVoteStatusEnum;
import com.yida.gwj.vote.service.IGwjBusinessDataService;
import com.yida.gwj.vote.service.IGwjVoteHouseService;
import com.yida.gwj.vote.service.IGwjVoteProjectService;
import com.yida.gwj.vote.service.IGwjVoteStatisticsService;
import com.yida.system.api.RemoteFileService;
import com.yida.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * @author lqq
 * @date 2023-03-10
 */
@Api(tags = "投票项目")
@RestController
@RequestMapping("/project")
public class GwjVoteProjectController extends BaseController {

    @Resource
    private IGwjVoteProjectService voteProjectService;

    @Resource
    private IGwjBusinessDataService gwjBusinessDataService;

    @Resource
    private IGwjVoteStatisticsService voteProjectStatistics;

    @Resource
    private IGwjVoteHouseService voteHouseService;

    @Resource
    private RemoteFileService remoteFileService;

    @ApiOperation(value = "查询电子投票列表", response = GwjVoteProjectListDTO.class)
    @RequiresPermissions("gwj:vote:e:project:list")
    @GetMapping("/e/list")
    public TableDataInfo eList(GwjVoteProjectQueryRequest request) {
        request.setInitiateType(GwjVoteInitiateTypeEnum.E_VOTE.getCode());
        startPage();
        List<GwjVoteProject> list = voteProjectService.selectVoteProjectList(BeanUtil.copyProperties(request, GwjVoteProject.class));
        list.forEach(p -> {
            if (p.getVoteStatus().equals(GwjVoteStatusEnum.VOTE_ING.getCode()) && DateUtil.compare(DateUtils.getNowDate(), p.getEndTime()) > 0) {
                p.setVoteStatus(GwjVoteStatusEnum.VOTE_END.getCode());
            }
        });
        return getDataDtoTable(list, GwjVoteProjectListDTO.class);
    }

    @ApiOperation(value = "查询公维金投票列表", response = GwjVoteProjectListDTO.class)
    @RequiresPermissions("gwj:vote:g:project:list")
    @GetMapping("/g/list/{bizNum}")
    public TableDataInfo gList(@PathVariable Long bizNum) {
        startPage();
        List<GwjVoteProject> list = voteProjectService.selectVoteProjectList(new GwjVoteProject() {{
            setBizNum(bizNum);
        }});
        list.forEach(p -> {
            if (p.getVoteStatus().equals(GwjVoteStatusEnum.VOTE_ING.getCode()) && DateUtil.compare(DateUtils.getNowDate(), p.getEndTime()) > 0) {
                p.setVoteStatus(GwjVoteStatusEnum.VOTE_END.getCode());
            }
        });
        return getDataDtoTable(list, GwjVoteProjectListDTO.class);
    }

    @ApiOperation(value = "获取投票详细信息", response = GwjVoteProjectDetailDTO.class)
    @GetMapping(value = "/{voteId}")
    @RequiresPermissions(value = {"gwj:vote:e:project:query", "gwj:vote:g:project:query"}, logical = Logical.OR)
    public AjaxResult getInfo(@PathVariable("voteId") Long voteId) {
        return AjaxResult.success(voteProjectService.voteDetail(voteId));
    }

    @ApiOperation(value = "根据条件查询房屋信息", response = GwjVoteHouse.class)
    @RequiresPermissions("gwj:vote:e:project:query")
    @PostMapping("/houseInfo")
    public TableDataInfo houseInfo(@Validated @RequestBody GwjVoteHouseQueryRequest request) {
        startPage();
        List<GwjVoteHouse> list = voteHouseService.selectVoteHouseList(BeanUtil.copyProperties(request, GwjVoteHouse.class));
        return getDataTable(list);
    }

    @ApiOperation(value = "投票新增")
    @RequiresPermissions("gwj:vote:g:project:add")
    @Log(title = "公维金内网投票-新增", businessType = BusinessType.INSERT, systemName = "vote")
    @PostMapping("/add")
    public AjaxResult add(@Validated(Save.class) @RequestBody GwjVoteProjectRequest request) {
        //校验业务状态
        GwjMaintenanceFundsBusiness business = gwjBusinessDataService.checkMaintenanceFundsBusinessStatus(request.getBizId());
        //校验投票是否已存在
        voteProjectService.checkVoteProjectExist(business.getBizNum());
        //校验时间参数
        if (DateUtil.compare(DateUtils.getNowDate(), request.getStartTime()) >= 0) {
            throw new ServiceException("投票发起时间必须大于当前的时间");
        }
        if (DateUtil.compare(request.getStartTime(), request.getEndTime()) >= 0) {
            throw new ServiceException("投票结束时间必须大于投票发起时间");
        }
        //查询基础数据楼栋、房屋、业主所有数据
        request.setBizNum(business.getBizNum());
        GwjBaseHouseOwnerDTO dto = gwjBusinessDataService.getAllDataByBizId(request.getBizId());
        return toAjax(voteProjectService.addVote(request, dto));
    }

    @ApiOperation("公维金投票修改")
    @RequiresPermissions("gwj:vote:g:project:edit")
    @Log(title = "公维金内网投票-公维金投票修改", businessType = BusinessType.UPDATE, systemName = "vote")
    @PutMapping("/g/update")
    public AjaxResult gEdit(@Validated(Update.class) @RequestBody GwjVoteProjectRequest request) {
        return toAjax(voteProjectService.updateVote(request, false));
    }

    @ApiOperation("电子投票投票修改")
    @RequiresPermissions("gwj:vote:e:project:edit")
    @Log(title = "公维金内网投票-电子投票修改", businessType = BusinessType.UPDATE, systemName = "vote")
    @PutMapping("/e/update")
    public AjaxResult eEdit(@Validated(Update.class) @RequestBody GwjVoteProjectRequest request) {
        return toAjax(voteProjectService.updateVote(request, true));
    }

    @ApiOperation("投票项目审批同意")
    @RequiresPermissions("gwj:vote:e:project:audit")
    @Log(title = "公维金内网投票-审批同意", businessType = BusinessType.UPDATE, systemName = "vote")
    @PostMapping("/agree")
    public AjaxResult agree(@Validated @RequestBody GwjVoteAuditRequest request) {
        return toAjax(voteProjectService.voteAudit(request, true));
    }

    @ApiOperation("投票项目审批不同意")
    @RequiresPermissions("gwj:vote:e:project:audit")
    @Log(title = "公维金内网投票-审批不同意", businessType = BusinessType.UPDATE, systemName = "vote")
    @PostMapping("/disagree")
    public AjaxResult disagree(@Validated @RequestBody GwjVoteAuditRequest request) {
        return toAjax(voteProjectService.voteAudit(request, false));
    }

    @ApiOperation("取消投票")
    @RequiresPermissions(value = {"gwj:vote:e:project:cancel", "gwj:vote:g:project:cancel"}, logical = Logical.OR)
    @Log(title = "公维金内网投票-取消投票", businessType = BusinessType.DELETE, systemName = "vote")
    @DeleteMapping("/cancel/{voteId}")
    public AjaxResult cancel(@PathVariable Long voteId) {
        return toAjax(voteProjectService.voteCancel(voteId));
    }

    @ApiOperation("发起投票")
    @RequiresPermissions(value = {"gwj:vote:e:project:start", "gwj:vote:g:project:start"}, logical = Logical.OR)
    @Log(title = "公维金内网投票-发起投票", businessType = BusinessType.UPDATE, systemName = "vote")
    @GetMapping("/start/{voteId}")
    public AjaxResult start(@PathVariable Long voteId) {
        return toAjax(voteProjectService.voteStart(voteId));
    }

    @ApiOperation(value = "短信通知")
    @RequiresPermissions(value = {"gwj:vote:e:project:sendSms", "gwj:vote:g:project:sendSms"}, logical = Logical.OR)
    @Log(title = "公维金内网投票-短信投票", businessType = BusinessType.OTHER, systemName = "vote")
    @GetMapping("/smsNotification/{voteId}")
    public AjaxResult smsNotification(@PathVariable Long voteId) {
        return toAjax(voteProjectService.voteSmsNotification(voteId));
    }

    @ApiOperation(value = "电子投票图表显示", response = GwjEVoteProjectStatisticsDataDTO.class)
    @RequiresPermissions("gwj:vote:e:project:statistics")
    @GetMapping("/e/statistics/{voteId}")
    public AjaxResult eVoteProjectStatistics(@PathVariable Long voteId) {
        return AjaxResult.success(new GwjEVoteProjectStatisticsDataDTO() {{
            setBaseData(voteProjectStatistics.eVoteProjectStatisticsBaseData(voteId));
            setItemData(voteProjectStatistics.voteResultDetailStatistics(voteId));
        }});
    }

    @ApiOperation(value = "公维金投票图表显示", response = GwjGVoteProjectStatisticsDataDTO.class)
    @RequiresPermissions("gwj:vote:g:project:statistics")
    @GetMapping("/g/statistics/{voteId}")
    public AjaxResult gVoteProjectStatistics(@PathVariable Long voteId) {
        return AjaxResult.success(voteProjectStatistics.gVoteProjectStatistics(voteId));
    }

    @InnerAuth
    @GetMapping("/inner/g/statistics/{bizNum}")
    public R<GwjGVoteProjectStatisticsDataDTO> innerGVoteProjectStatistics(@PathVariable Long bizNum) {
        GwjVoteProject gwjVoteProject = voteProjectService.selectVoteProject(new GwjVoteProject() {{
            setBizNum(bizNum);
            setVoteStatus(GwjVoteStatusEnum.VOTE_ING.getCode());
        }});
        if (StringUtils.isNull(gwjVoteProject)) {
            return R.fail("查无投票项目");
        }
        return R.ok(voteProjectStatistics.gVoteProjectStatistics(gwjVoteProject.getVoteId()));
    }

    @ApiOperation("投票项目上传投票内容图片")
    @Log(title = "公维金内网投票-上传投票内容图片", businessType = BusinessType.UPDATE, systemName = "vote")
    @PostMapping(value = "/uploadImg")
    @RequiresPermissions(value = {"gwj:vote:g:project:add", "gwj:vote:g:project:edit"}, logical = Logical.OR)
    public AjaxResult uploadImg(MultipartFile file) {
        if (file != null && !file.isEmpty()) {
            String extension = FileTypeUtils.getExtension(file);
            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
                return AjaxResult.error("上传图片失败,图片格式不正确" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
            }
            R<SysFile> fileResult = remoteFileService.upload(file);
            if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) {
                return AjaxResult.error("上传图片失败,图片服务异常");
            }
            return AjaxResult.success("上传图片成功", fileResult.getData().getUrl());
        }
        return AjaxResult.error("上传图片失败,图片异常");
    }
}
